package gis

import (
	"dgo/goutils/utils"
)

type GGADecoder struct {
	decodeState  int
	starIdx      int // 星号的索引
	cache        utils.BytesBuilder
	LastNmeaText string
	OnNmea       func(sender *GGADecoder, nmea string)
}

var (
	__gga_buf = []byte("GGA")
)

func NewGGADecoder() *GGADecoder {
	rval := &GGADecoder{}
	return rval
}

func (this *GGADecoder) Reset() {
	this.cache.Reset()
	this.decodeState = 1
	this.starIdx = 0
}

func (this *GGADecoder) InputText(txt string) {
	this.InputBuf([]byte(txt))
}

func (this *GGADecoder) InputBuf(buf []byte) int {
	rval := 0
	for i := 0; i < len(buf); i++ {
		if this.InputByte(buf[i]) == 1 {
			rval++
		}
	}
	return rval
}

func (this *GGADecoder) GetNMEAText() string {
	return this.cache.String()
}

func (this *GGADecoder) CacheBuf() []byte {
	return this.cache.Bytes()
}

func (this *GGADecoder) InputByte(v byte) int {
	if this.decodeState <= 0 {
		this.Reset()
	}

	this.cache.WriteByte(v)
	l := this.cache.Len()
	if l < 8 {
		if v == '$' && l > 1 { // $$GPGGA
			this.cache.Delete(0, l-1)
			return 0
		}
		if IsNmeaChr(v) {
			return 0
		}
		this.decodeState = -1
		return 0
	} else if l == 8 { // GPGGA, $GPGGA, $GNGGA   // 最小的GGA长度
		if !IsNmeaChr(v) {
			this.decodeState = -1
			return 0
		}

		idx := this.cache.Index(0, __gga_buf)
		if idx == -1 {
			this.cache.Delete(0, 1) // 清理掉一个
			return 0
		}
		return 0
	} else {
		if this.starIdx > 0 {
			if this.starIdx+3 == this.cache.Len() { // 校验码
				this.decodeState = 0
				nmeaStr := this.cache.String()
				this.LastNmeaText = nmeaStr
				if this.OnNmea != nil {
					this.OnNmea(this, nmeaStr)
				}
				return 1
			}
		} else {
			if this.cache.Len() > 128 { // 超过128 还没有结束
				this.decodeState = -1
				return -1
			}
			if v == '*' {
				this.starIdx = this.cache.Len() - 1 // 星号的位置
			}
		}
	}

	return 0

}
